package com.xmy.cultivate.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmy.cultivate.entity.*;
import com.xmy.cultivate.mapper.*;
import com.xmy.cultivate.respons.LackCourseLogRs;
import com.xmy.cultivate.service.*;
import com.xmy.cultivate.util.*;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 缺课记录 前端控制器
 * </p>
 *
 * @author hpiggy
 * @since 2023-07-28
 */
@RestController
@RequestMapping("/api/lackCourseLog")
@Scope("prototype")
public class LackCourseLogController extends BaseController {
    @Autowired
    ILackCourseLogService iLackCourseLogService;

    @Autowired
    IStudentService iStudentService;

    @Autowired
    CourseSchedulingAlwaysMapper courseSchedulingAlwaysMapper;

    @Autowired
    IRepairCourseService iRepairCourseService;

    @Autowired
    CourseMapper courseMapper;

    @Autowired
    IRecordCourseService iRecordCourseService;

    @Autowired
    ICourseSchedulingDetailService iCourseSchedulingDetailService;

    @GetMapping()
    @ApiOperation("查询缺课记录")
    public Result searchScheduling(@RequestParam Map reMap,
                                   @RequestParam(value = "yearClassId", defaultValue = "", required = false) String yearClassId,
                                   @RequestParam(value = "classTypeId", defaultValue = "", required = false) String classTypeId,
                                   @RequestParam(value = "lessonType", defaultValue = "", required = false) String lessonType,
                                   @RequestParam(value = "lessonNum", defaultValue = "", required = false) String lessonNum,
                                   @RequestParam(value = "isRepair", required = false) List<String> isRepairList) {
        Integer pageNum = StringUtils.isEmpty((String) reMap.get("pageNum")) ? 1 : Integer.valueOf((String) reMap.get("pageNum"));
        Integer pageSize = StringUtils.isEmpty((String) reMap.get("pageSize")) ? 10 : Integer.valueOf((String) reMap.get("pageSize"));
        Page<LackCourseLog> iPage = new Page<>(pageNum, pageSize);

        String yearPart = (String) reMap.get("yearPart");
        String quarterNum = (String) reMap.get("quarterNum");
        String schoolId = (String) reMap.get("schoolId");
        String gradeId = (String) reMap.get("gradeId");
        String schoolDate = (String) reMap.get("schoolDate");
        //String isRepair = (String) reMap.get("isRepair");
        String studentName = (String) reMap.get("name");
        String teacherId = (String) reMap.get("teacherId");
        String subjectsId = (String) reMap.get("subjectsId");

        QueryWrapper<LackCourseLog> queryWrapper = new QueryWrapper();
        queryWrapper.eq(StringUtils.isNotBlank(yearPart), "lack_course_log.year_part", yearPart);
        queryWrapper.eq(StringUtils.isNotBlank(quarterNum), "lack_course_log.quarter_num", quarterNum);
        queryWrapper.inSql(StringUtils.isNotBlank(schoolId), "lack_course_log.school_id", schoolId);
        queryWrapper.eq(StringUtils.isNotBlank(gradeId), "lack_course_log.grade_id", gradeId);
        queryWrapper.eq(StringUtils.isNotBlank(teacherId), "grade.teacher_id", teacherId);
        queryWrapper.eq(StringUtils.isNotBlank(subjectsId), "lack_course_log.subjects_id", subjectsId);
        queryWrapper.eq(StringUtils.isNotBlank(lessonType), "grade.lesson_type", lessonType);
        queryWrapper.inSql(StringUtils.isNotBlank(classTypeId), "grade.course_type_id", classTypeId);
        queryWrapper.inSql(StringUtils.isNotBlank(yearClassId), "grade.year_class_id", yearClassId);
        queryWrapper.eq(StringUtils.isNotBlank(lessonNum), "lack_course_log.lesson_num", lessonNum);
        queryWrapper.eq("lack_course_log.deleted", 0);
        queryWrapper.inSql("lack_course_log.status", "0,1");

        //未安排
        if (isRepairList.size() > 0) {
            Collections.sort(isRepairList);
            String sql = "(";
            for (String isRepair : isRepairList) {
                if (isRepair.equals("0")) {
                    //未安排的is_repair为0或者is_repair为2并且结束时间小于等于当前时间
                    sql += "(is_repair=" + isRepair + " or (is_repair=2 and repair_end_date_time<='" + LocalDateTime.now().withNano(0) + "'))";
                    //queryWrapper.and(i -> i.eq("is_repair", isRepair).or(j -> j.eq("is_repair", 2).le("repair_end_date_time", LocalDateTime.now().withNano(0))));
                } else if ("1".equals(isRepair)) {
                    //queryWrapper.eq("is_repair", isRepair);
                    if (isRepairList.contains("0")) {
                        sql += "or";
                    }
                    sql += "(is_repair = 1)";
                } else if ("2".equals(isRepair)) {
                    //0未安排，1，已补课，2已按排
                    if (isRepairList.contains("0") || isRepairList.contains("1")) {
                        sql += "or";
                    }
                    sql += " (is_repair=2 and repair_end_date_time>='" + LocalDateTime.now().withNano(0) + "')";
                    //queryWrapper.eq("is_repair", isRepair);
                    //queryWrapper.ge("repair_end_date_time", LocalDateTime.now().withNano(0));
                }
            }
            sql += ")";
            queryWrapper.apply(sql);
        }

        if (StringUtils.isNotBlank(schoolDate)) {
            queryWrapper.inSql("lack_course_log.id", "select record_course_id from repair_course where school_date ='" + schoolDate + "' and deleted=0");
        }
        if (StringUtils.isNotBlank(studentName)) {
            /*QueryWrapper wrapperByName = new QueryWrapper<>();
            wrapperByName.like("name", name);
            List<Long> studentIds = studentMapper.getStudentIds(wrapperByName);
            if (studentIds.size() != 0) {
                queryWrapper.and(wrapper -> studentIds.forEach(per -> wrapper.or(o -> o.eq("lack_course_log.student_id", per))));
            } else {
                queryWrapper.eq("lack_course_log.student_id", 0);
            }*/

            queryWrapper.inSql("lack_course_log.student_id", "select id from student where name like'%" + studentName + "%' and deleted=0");
        }
        if (this.sourseLeve.equals(2)) {
            queryWrapper.inSql("lack_course_log.grade_id", "select id from grade where teacher_id =" + this.adminId);
        }


        iLackCourseLogService.getLackCourseLog(iPage, queryWrapper);

        for (LackCourseLog lackCourseLog : iPage.getRecords()) {
            RepairCourse repairCourse = iRepairCourseService.getById(lackCourseLog.getRepairId());
            if (repairCourse != null) {
                //是否已经补课
                if (repairCourse.getIsSignIn().equals(1)) {
                    RecordCourse recordCourse = iRecordCourseService.getOne(new QueryWrapper<RecordCourse>().eq("scheduling_detail_id", repairCourse.getId()).last("limit 1"));
                    if (recordCourse != null) {
                        lackCourseLog.setIsRepair(1);
                    }
                }

                if (lackCourseLog.getIsRepair() != 1 && repairCourse.getEndDateTime().isBefore(LocalDateTime.now())) {
                    lackCourseLog.setRepairEndDateTime(null);
                    lackCourseLog.setIsRepair(0);
                } else {
                    lackCourseLog.setRepairEndDateTime(repairCourse.getEndDateTime());
                    if (repairCourse.getStartDateTime() != null && repairCourse.getEndDateTime() != null) {
                        String startDateR = repairCourse.getStartDateTime().toString();
                        startDateR = startDateR.substring(startDateR.length() - 5);
                        String endDateR = repairCourse.getEndDateTime().toString();
                        endDateR = endDateR.substring(endDateR.length() - 5);
                        lackCourseLog.setRepairDateStr(repairCourse.getSchoolDate() + " " + startDateR + "-" + endDateR);
                    }
                }
                if (repairCourse.getStartDateTime() != null && repairCourse.getEndDateTime() != null) {
                    String startDateR = repairCourse.getStartDateTime().toString();
                    startDateR = startDateR.substring(startDateR.length() - 5);
                    String endDateR = repairCourse.getEndDateTime().toString();
                    endDateR = endDateR.substring(endDateR.length() - 5);
                    lackCourseLog.setPassRepairDateStr(repairCourse.getSchoolDate() + " " + startDateR + "-" + endDateR);
                }

                lackCourseLog.setRepairGradeName(repairCourse.getGradeName());
                lackCourseLog.setRepairTeacherName(repairCourse.getTeacherName());
            } else {
                lackCourseLog.setRepairEndDateTime(null);
                lackCourseLog.setIsRepair(0);
            }

            if (lackCourseLog.getSchedulingAlwaysId() != null) {
                //这里是旧版本写法，以后要删除掉
                CourseSchedulingAlways courseSchedulingAlways = courseSchedulingAlwaysMapper.getDate(lackCourseLog.getSchedulingAlwaysId());
                if (courseSchedulingAlways != null) {
                    lackCourseLog.setStartDate(courseSchedulingAlways.getStartDate());
                    lackCourseLog.setEndDate(courseSchedulingAlways.getEndDate());
                    lackCourseLog.setNum(courseSchedulingAlways.getNum());
                } else {
                    CourseSchedulingDetail courseSchedulingDetail = iCourseSchedulingDetailService.getById(lackCourseLog.getSchedulingAlwaysId());
                    if (courseSchedulingDetail != null) {
                        lackCourseLog.setStartDate(courseSchedulingDetail.getSchoolDate());
                        lackCourseLog.setNum(courseSchedulingDetail.getLessonNum());
                        lackCourseLog.setTimeStart(courseSchedulingDetail.getTimeStart());
                        lackCourseLog.setTimeEnd(courseSchedulingDetail.getTimeEnd());
                    }
                }
            }
            lackCourseLog.setStudentName(iStudentService.getStudentName(lackCourseLog.getStudentId()));
            lackCourseLog.setCourseName(courseMapper.getCourseName(lackCourseLog.getCourseId()));
        }
        return new Result(Code.GET_OK, new PageResult(iPage.getRecords(), iPage.getTotal(), iPage.getPages()), "查询成功~");
    }

    @DeleteMapping()
    @ApiOperation("取消补课安排")
    public Result removeScheduling(@RequestParam("id") String id) {
        LackCourseLog lackCourseLog = iLackCourseLogService.getById(id);
        if (lackCourseLog == null) {
            return new Result(Code.DELETE_ERROR, Code.DELETE_ERROR_MSG, "该记录不存在");
        }
        Integer isRepair = lackCourseLog.getIsRepair();
        if (isRepair != null) {
            if (isRepair == 0) {
                return new Result(Code.DELETE_ERROR, Code.DELETE_ERROR_MSG, "该学员未安排补课");
            }
            if (isRepair == 1) {
                return new Result(Code.DELETE_ERROR, Code.DELETE_ERROR_MSG, "该学员已补课");
            }
        } else {
            return new Result(Code.DELETE_ERROR, Code.DELETE_ERROR_MSG, "该学员未安排补课");
        }
        RepairCourse repairCourse = iRepairCourseService.getById(lackCourseLog.getRepairId());
        if (repairCourse == null) {
            return new Result(Code.DELETE_ERROR, Code.DELETE_ERROR_MSG, "该学员未安排补课信息");
        }
        //是否已经补课
        if (repairCourse.getIsSignIn().equals(1)) {
            RecordCourse recordCourse = iRecordCourseService.getOne(new QueryWrapper<RecordCourse>().eq("scheduling_detail_id", repairCourse.getId()).last("limit 1"));
            if (recordCourse != null) {
                return new Result(Code.ERROR, "", "该学员已经补课，不能取消");
            }
        }


        //将排课状态和排课id改为0
        iLackCourseLogService.updateRemarkBoolean(0, 0L, Long.valueOf(id));
        Boolean remove = iRepairCourseService.removeById(lackCourseLog.getRepairId());
        return new Result(remove ? Code.DELETE_OK : Code.DELETE_ERROR, "", remove ? Code.DELETE_OK_MSG : Code.DELETE_ERROR_MSG);
    }

    @PostMapping("/deleteLack")
    @ApiOperation("删除缺课信息")
    public Result deleteLack(@RequestBody Map repMap) {

        List<String> idList = (List<String>) repMap.get("idList");
        Integer i = 0;
        for (String id : idList) {
            LackCourseLog lackCourseLog = iLackCourseLogService.getById(Long.parseLong(id));
            if (lackCourseLog == null) {
                continue;
            }
            if (lackCourseLog.getIsRepair().equals(1)) {
                continue;
            }
            if (lackCourseLog.getRepairId() != null) {
                RepairCourse repairCourse = iRepairCourseService.getById(lackCourseLog.getRepairId());
                if (repairCourse != null) {
                    //是否已经补课
                    if (repairCourse.getIsSignIn().equals(1)) {
                        RecordCourse recordCourse = iRecordCourseService.getOne(new QueryWrapper<RecordCourse>().eq("scheduling_detail_id", repairCourse.getId()).last("limit 1"));
                        if (recordCourse != null) {
                            return new Result(Code.ERROR, "", "该学员已经补课，不能删除");
                        }
                    }
                }
            }

            QueryWrapper<RepairCourse> repairCourseQueryWrapper = new QueryWrapper<>();
            repairCourseQueryWrapper.eq("record_course_id", id);
            iRepairCourseService.remove(repairCourseQueryWrapper);
            //将排课状态和排课id改为0
            iLackCourseLogService.removeById(Long.parseLong(id));
            i++;
        }
        return new Result(Code.DELETE_OK, "", "成功删除:" + i + "条数据");
    }


    @GetMapping("/lackStudentList")
    @ApiOperation("缺课学员")
    public Result lackStudentList(@RequestParam(value = "pageNum", defaultValue = "-1", required = false) Integer pageNum,
                                  @RequestParam(value = "pageSize", defaultValue = "-1", required = false) Integer pageSize,
                                  @RequestParam(value = "yearPart", defaultValue = "", required = false) Integer yearPart,
                                  @RequestParam(value = "quarterNum", defaultValue = "", required = false) Integer quarterNum,
                                  @RequestParam(value = "schoolId", defaultValue = "", required = false) String schoolId,
                                  @RequestParam(value = "yearClassId", defaultValue = "", required = false) String yearClassId,
                                  @RequestParam(value = "gradeId", defaultValue = "", required = false) String gradeId,
                                  @RequestParam(value = "subjectsId", defaultValue = "", required = false) String subjectsId,
                                  @RequestParam(value = "teacherId", defaultValue = "", required = false) String teacherId,
                                  @RequestParam(value = "classTypeId", defaultValue = "", required = false) String classTypeId,
                                  @RequestParam(value = "lackType", defaultValue = "", required = false) String lackType,// 0是功能更新前数据，功能更新后：1为分班（新生）缺课，2停课复课缺课
                                  @RequestParam(value = "studentName", defaultValue = "", required = false) String studentName,
                                  @RequestParam(value = "idStr", defaultValue = "", required = false) String idStr,
                                  @RequestParam(value = "export", defaultValue = "0", required = false) Integer export// 是否导出，0否1是
    ) throws IOException {
        IPage<LackCourseLogRs> iPage = new Page<>(pageNum, pageSize);

        iLackCourseLogService.lackStudentList(iPage, yearPart, quarterNum, schoolId, yearClassId, gradeId, subjectsId, teacherId, classTypeId, lackType, studentName, idStr);

        if (export == 1) {

            CellRangeAddress cellRangeAddress = CellRangeAddress.valueOf("A1:H1");
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("Sheet1");
            sheet.createFreezePane(0, 1);
            sheet.setAutoFilter(cellRangeAddress);

            Row headerRow = sheet.createRow(0);
            headerRow.setHeightInPoints(30);

            CellStyle headerCellStyle = ExcelUtils.headCommonCellStyle(workbook);

            CellStyle cellStyle = ExcelUtils.bodyCommonCellStyle(workbook, null);

            List<String> headList = new ArrayList<>();
            headList.add("学员姓名");
            headList.add("班级");
            headList.add("年级");
            headList.add("班型");
            headList.add("科目");
            headList.add("缺课课次");
            headList.add("教师");
            headList.add("状态");

            for (int i = 0; i < headList.size(); i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headList.get(i));
                cell.setCellStyle(headerCellStyle);
                sheet.setColumnWidth(i, 25 * 256);
            }

            int rowIndex = 1;

            for (LackCourseLogRs lackCourseLogRs : iPage.getRecords()) {
                Row row = sheet.createRow(rowIndex);

                Cell cell0 = row.createCell(0);
                cell0.setCellValue(lackCourseLogRs.getStudentName());
                sheet.setColumnWidth(0, 25 * 256);
                cell0.setCellStyle(cellStyle);

                Cell cell1 = row.createCell(1);
                cell1.setCellValue(lackCourseLogRs.getGradeName());
                sheet.setColumnWidth(1, 25 * 256);
                cell1.setCellStyle(cellStyle);

                Cell cell2 = row.createCell(2);
                if (lackCourseLogRs.getYearClassId() != null) {
                    cell2.setCellValue(CommonUtil.getYearClassNameForId(lackCourseLogRs.getYearClassId()));
                }
                sheet.setColumnWidth(2, 15 * 256);
                cell2.setCellStyle(cellStyle);

                Cell cell3 = row.createCell(3);
                cell3.setCellValue(lackCourseLogRs.getClassTypeName());
                sheet.setColumnWidth(3, 15 * 256);
                cell3.setCellStyle(cellStyle);

                Cell cell4 = row.createCell(4);
                cell4.setCellValue(lackCourseLogRs.getSubjectsName());
                sheet.setColumnWidth(4, 15 * 256);
                cell4.setCellStyle(cellStyle);

                Cell cell5 = row.createCell(5);
                cell5.setCellValue(lackCourseLogRs.getLessonNum());
                sheet.setColumnWidth(5, 60 * 256);
                cell5.setCellStyle(cellStyle);

                Cell cell6 = row.createCell(6);
                cell6.setCellValue(lackCourseLogRs.getTeacherName());
                sheet.setColumnWidth(6, 15 * 256);
                cell6.setCellStyle(cellStyle);

                Cell cell7 = row.createCell(7);
                if (lackCourseLogRs.getLackType() != null) {
                    if (lackCourseLogRs.getLackType() == 0) {
                        cell7.setCellValue("无");
                    } else if (lackCourseLogRs.getLackType() == 1) {
                        cell7.setCellValue("新生缺课");
                    } else if (lackCourseLogRs.getLackType() == 2) {
                        cell7.setCellValue("停课缺课");
                    }
                }
                sheet.setColumnWidth(7, 15 * 256);
                cell7.setCellStyle(cellStyle);

                rowIndex++;
            }

            String fileName = "业绩数据" + ".xlsx";
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8");

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");//设置为excel格式
            response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);//设置响应头

            // 获取响应输出流
            OutputStream outputStream = response.getOutputStream();

            // 将工作簿写入输出流
            workbook.write(outputStream);

            // 关闭工作簿
            workbook.close();

            // 刷新输出流
            outputStream.flush();

            //关闭输出流
            outputStream.close();
        }

        return new Result(Code.OK, new PageResult(iPage.getRecords(), iPage.getTotal(), iPage.getPages()));
    }

    @PostMapping("/updateLackType")
    @ApiOperation("修改缺课类型")
    public Result updateLackType(@RequestBody LackCourseLogRs lackCourseLogRs) {
        List<LackCourseLogRs> lackCourseLogList = lackCourseLogRs.getLackCourseLogRsList();
        Integer yearPart = lackCourseLogRs.getYearPart();
        Integer quarterNum = lackCourseLogRs.getQuarterNum();
        Integer lackType = lackCourseLogRs.getLackType();

        for (LackCourseLogRs lackCourseLog : lackCourseLogList) {
            iLackCourseLogService.updateLackTypeBoolean(lackType, lackCourseLog.getGradeId(), lackCourseLog.getStudentId(), yearPart, quarterNum);
        }

        return new Result(Code.OK, "", Code.OK_MSG);
    }

    @PostMapping("/cancelLack")
    @ApiOperation("取消/恢复缺课")
    public Result cancelLack(@RequestBody LackCourseLogRs lackCourseLogRs) {
        List<LackCourseLogRs> lackCourseLogList = lackCourseLogRs.getLackCourseLogRsList();
        Integer yearPart = lackCourseLogRs.getYearPart();
        Integer quarterNum = lackCourseLogRs.getQuarterNum();

        HashMap<String, Integer> hashMap = new HashMap<>();
        hashMap.put("finish", yearPart);
        hashMap.put("unfinished", quarterNum);

        StringBuilder stringBuilder = new StringBuilder();


        for (LackCourseLogRs lackCourseLog : lackCourseLogList) {
            // 删除lack_course_log缺课记录
            iLackCourseLogService.cancelLackBoolean(lackCourseLog.getGradeId(), lackCourseLog.getStudentId(), yearPart, quarterNum);
            // 删除repair_course记录
            iLackCourseLogService.cancelRepairCourseBoolean(lackCourseLog.getGradeId(), lackCourseLog.getStudentId(), yearPart, quarterNum);
        }

        return new Result(Code.OK, stringBuilder, Code.OK_MSG);
    }
}
